<?php
namespace other\orders;
use DdConstant\Shop;
use other\orders\fx\Airwallex;
use other\ShopingConn;
use other\Table;
use think\Db;
use think\db\exception\DbException;
use think\Exception;
use think\exception\PDOException;

/**
 * 订单的异常情况
 */
class Abnornal
{
    //
    private $run_paypal = 1;
    private $run_pk = 1;
    private $run_yh = 1;

    // 日期-小时
    private $dh;

    // todo  重要参数
    private $event_orders_asc = [
        'charged.debited-ended.list_used' => 'charged.debited',
        'paid_out.paid_out-paid_out.refund_credited' => 'paid_out.refund_credited',
        'charged.paid_out_partial-paid_out.refund_credited' => 'charged.paid_out_partial',
        'aborted.list_aborted-declined.debit_declined' => 'declined.debit_declined',
        'charged.resolution_in_progress-paid_out.auto_resolved' => 'paid_out.auto_resolved',
        'payment_intent.created-payment_intent.requires_payment_method' => 'payment_intent.requires_payment_method',
        'payment_attempt.authorized-payment_attempt.capture_requested-payment_intent.succeeded' => 'payment_intent.succeeded',
        'payment_attempt.authentication_failed-payment_intent.requires_payment_method' => 'payment_attempt.authentication_failed',
        'payment_attempt.authorization_failed-payment_intent.requires_payment_method' => 'payment_attempt.authorization_failed',
        'payment_attempt.expired-payment_intent.requires_payment_method' => 'payment_attempt.expired',
        'payment_attempt.capture_requested-payment_intent.succeeded' => 'payment_intent.succeeded',
        'payment_attempt.received-payment_attempt.risk_declined' => 'payment_attempt.risk_declined',
        'payment_attempt.authorized-payment_attempt.capture_requested-payment_attempt.received-payment_intent.succeeded' => 'payment_intent.succeeded',
        'payment_attempt.authentication_redirected-payment_intent.requires_customer_action' => 'payment_intent.requires_customer_action',
        'payment_attempt.authentication_redirected-payment_attempt.received-payment_intent.requires_customer_action' => 'payment_intent.requires_customer_action',
        'payment_attempt.authentication_redirected-payment_attempt.received' => 'payment_attempt.authentication_redirected',
        'payment_attempt.authentication_redirected-payment_attempt.cancelled-payment_attempt.received-payment_intent.requires_customer_action' => 'payment_intent.requires_customer_action',
    ];


    /**
     * 处理    Abnormal
     * @return void
     * @throws Exception
     */
    public function do()
    {
        $now_time = time();

        $this->_event_order();
        // 补全 推送日志的 event 等字段
        $this->_event();
//        $this->_event_dic();

//        $this->run_paypal = 1;
//        $this->run_pk = 0;
        $this->dh = date('ymdH',$now_time-3600);
        $this->_do();
        $this->dh = date('ymdH',$now_time);
        $this->_do();

//        $handel = new Airwallex();
//        $handel->do();
//        var_dump(6);
        exit();
    }

    private function _do(){
        var_dump(1);
        // 补全 推送日志的 order_id 字段
        $this->_log_bz_id();
        var_dump(2);
        $this->_log_order_id();
        var_dump(3);
        $this->_log_order_id2();
        var_dump(4);
        $this->_event_order_main();
        var_dump(5);
    }

    /////////////////////////////////////////////////////////////// todo  日志匹配 订单ID
    /**
     * notify_log 表的数据，order_id 赋值
     * @return void
     * @throws Exception
     */
    private function _log_order_id()
    {
        var_dump(31);
        if ($this->run_pk)
        {
            // P 卡 的 订单id的找回
            $paypal_method = 3;
            ShopingConn::getConn()
                ->table(Table::Table_Order_Notify_Logs)
                ->where('dh',$this->dh)
                ->where('order_id',0)
                ->where('paypal_method',$paypal_method)
                ->chunk(100,function ($datas)use($paypal_method){
                    if ($datas)
                    {
                        foreach ($datas as $data)
                        {
                            $params = $data['params'];
                            $params = json_decode($params,true);
                            $is_fill = false;

                            // 1 . 根据 paypal_order_id 去处理
                            if (isset($params['longId']) && $longId = $params['longId'])
                            {
                                $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('paypal_order_id', $longId)
                                    ->where('paypal_method',$paypal_method)->value('id');
                                if ($order_id){
                                    $this->_update_notify_logs_order_id($data['id'],$order_id);
                                    $is_fill = true;
                                }
                            }

                            if (!$is_fill){
                                //2 .  order_sn
                                if (isset($params['transactionId']) && $transactionId = $params['transactionId'])
                                {
                                    $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('order_sn', $transactionId)
                                        ->where('paypal_method',$paypal_method)->value('id');
                                    if ($order_id){
                                        $this->_update_notify_logs_order_id($data['id'],$order_id);
                                        $is_fill = true;
                                    }
                                }
                            }


                            if (!$is_fill){
                                //3 .  payment_id
                                if (isset($params['shortId']) && $shortId = $params['shortId'])
                                {
                                    $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('payment_id', $shortId)
                                        ->where('paypal_method',$paypal_method)->value('id');
                                    if ($order_id){
                                        $this->_update_notify_logs_order_id($data['id'],$order_id);
                                        $is_fill = true;
                                    }
                                }
                            }


                            if (!$is_fill){
                                // 4 . payer_id
                                if (isset($params['transactionId']) && $transactionId = $params['transactionId'])
                                {
                                    $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('payer_id', $transactionId)
                                        ->where('paypal_method',$paypal_method)->value('id');
                                    if ($order_id){
                                        $this->_update_notify_logs_order_id($data['id'],$order_id);
                                        $is_fill = true;
                                    }
                                }
                            }

                            if (!$is_fill){
                                $this->_update_notify_logs_order_id($data['id'],Table::ZWF_OrderId);
                            }
                        }
                    }
                });
        }
        var_dump(32);
        if ($this->run_paypal)
        {
            // PayPal 的 订单id的找回
            $paypal_method = 1;
            ShopingConn::getConn()
                ->table(Table::Table_Order_Notify_Logs)
                ->where('dh',$this->dh)
                ->where('order_id',0)
                ->where('paypal_method',$paypal_method)
                ->chunk(10,function ($datas)use($paypal_method)
                {
                    if ($datas)
                    {
                        foreach ($datas as $data)
                        {
                            $is_fill = false;
                            $params = $data['params'];
                            $params = json_decode($params,true);
                            if (isset($params['resource']) && $resource = $params['resource'])
                            {
                                if (isset($resource['id']) && $paypal_order_id = $resource['id']){
                                    $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('paypal_order_id', $paypal_order_id)
//                                        ->where('paypal_method',$paypal_method)
                                        ->value('id');
                                    if ($order_id){
                                        $this->_update_notify_logs_order_id($data['id'],$order_id);
                                        $is_fill = true;
                                    }
                                }

                                if (!$is_fill){
                                    if (isset($resource['supplementary_data']) && $supplementary_data = $resource['supplementary_data'])
                                    {
                                        if (isset($supplementary_data['related_ids']) && $related_ids = $supplementary_data['related_ids']){
                                            if (isset($related_ids['order_id']) && $paypal_order_id = $related_ids['order_id']){
                                                $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('paypal_order_id', $paypal_order_id)
                                                    ->where('paypal_method',$paypal_method)->value('id');
                                                if ($order_id){
                                                    $this->_update_notify_logs_order_id($data['id'],$order_id);
                                                }
                                            }
                                        }
                                    }
                                }
                            }


                            if (!$is_fill){
                                $this->_update_notify_logs_order_id($data['id'],Table::ZWF_OrderId);
                            }

                        }
                    }
                });
        }
        var_dump(33);
        if ($this->run_yh)
        {
            // 空中云汇 的 订单id的找回
            $paypal_method = 4;
            ShopingConn::getConn()
                ->table(Table::Table_Order_Notify_Logs)
                ->where('dh',$this->dh)
                ->where('order_id',0)
                ->where('paypal_method',$paypal_method)
                ->chunk(10,function ($datas)use($paypal_method)
                {
                    if ($datas)
                    {
                        foreach ($datas as $data)
                        {
                            $params = $data['params'];
                            if (strpos($params,'#'))
                            {
                                $params = json_decode($params,true);
                                if (!empty($params['id']) && $params_id = $params['id']){
                                    if (!strpos('a'.$params_id,'evt_')){
                                        continue;
                                    }
                                }

                                $paypal_order_id = '';
                                if (!empty($params['sourceId'])){
                                    $paypal_order_id = $params['sourceId'];
                                }
                                if (!$paypal_order_id){
                                    if (isset($need['id'])){
                                        $paypal_order_id = $need['id'];
                                    }
                                }


                                if ($paypal_order_id)
                                {
                                    $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('paypal_order_id', $paypal_order_id)
//                                        ->where('paypal_method',$paypal_method)
                                        ->value('id');
                                    if ($order_id){
                                        $this->_update_notify_logs_order_id($data['id'],$order_id);
                                    }else{

                                        // 给个默认值
                                        $this->_update_notify_logs_order_id($data['id'],1);

                                        // todo 当   paypal_order_id  有被修改时
//                                        $value = ShopingConn::getConn()->table(Table::Table_change_logs)
//                                            ->where('change_before', $paypal_order_id)
//                                            ->value('pid');
//                                        if (!$value){
//                                            $value = ShopingConn::getConn()->table(Table::Table_change_logs)
//                                                ->where('change_after', $paypal_order_id)
//                                                ->value('pid');
//                                        }
//
//                                        if ($value){
//                                            $this->_update_notify_logs_order_id($data['id'],$value);
//                                        }
                                    }
                                }



//                                if (isset($need['merchant_order_id']) && $transactionId = $need['merchant_order_id'])
//                                {
//                                    $order_id = ShopingConn::getConn()->table(Table::Table_Order)->where('order_sn', $transactionId)
//                                        ->where('paypal_method',$paypal_method)->value('id');
//                                    if ($order_id){
//
//                                        $this->_update_notify_logs_order_id($data['id'],$order_id);
//                                        continue;
//                                    }
//                                }
                            }
                        }
                    }
                });
        }
        var_dump(34);
    }


    private function _log_order_id2()
    {
        if ($this->run_yh)
        {
            // 云汇 的 订单id的找回
            $paypal_method = 4;
            ShopingConn::getConn()
                ->table(Table::Table_Order_Notify_Logs)
                ->where('dh',$this->dh)
                ->where('order_id',0)
                ->where('bz_id','<>','')
                ->where('paypal_method',$paypal_method)
                ->field('id,paypal_method,bz_id')
                ->chunk(10,function ($datas)use($paypal_method) {
                    if ($datas) {
                        foreach ($datas as $data) {
                            $this->_update_notify_logs_order_id_by_bz_id($data['id'],$data['bz_id']);
                        }
                    }
                });
        }
    }

    /**
     * @throws DbException
     * @throws Exception
     */
    private function _log_bz_id(){
        ShopingConn::getConn()
            ->table(Table::Table_Order_Notify_Logs)
            ->where('dh',$this->dh)
            ->where('bz_id','')
            ->chunk(10,function ($datas){
                if ($datas) {
                    foreach ($datas as $data) {
                        $params = $data['params'];
                        $params = json_decode($params,true);

                        if (isset($params['id']) && $bz_id = $params['id'])
                        {
                            switch ($data['paypal_method']){
                                case 4:
                                    if (strpos($bz_id,'_')){
                                        $bz_id = strrchr($bz_id,'_');
                                    }
                                    break;
                                default:break;
                            }
                                $this->_update_notify_logs_bz_id($data['id'],$bz_id);
                        }
                    }
                }
            });
    }


    /**
     * 更新表 notify_logs 的 order_id 字段
     * @param $id
     * @param $order_id
     * @return void
     * @throws Exception
     * @throws PDOException
     */
    private function _update_notify_logs_order_id($id,$order_id){
        ShopingConn::getConn()->table(Table::Table_Order_Notify_Logs)
            ->where('id',$id)->update(['order_id' => $order_id]);
    }

    private function _update_notify_logs_order_id_by_bz_id($id,$bz_id){

        $value = ShopingConn::getConn()->table(Table::Table_Order_Notify_Logs)
            ->where('bz_id', $bz_id)->where('id', 'between', [$id - 10, $id + 10])
            ->where('order_id', '>', 0)
            ->value('order_id');

        if ($value){
            ShopingConn::getConn()->table(Table::Table_Order_Notify_Logs)
                ->where('id',$id)->update(['order_id' => $value]);
        }
    }

    private function _update_notify_logs_bz_id($id,$bz_id){
        ShopingConn::getConn()->table(Table::Table_Order_Notify_Logs)
            ->where('id',$id)->update(['bz_id' => $bz_id]);
    }


    /**
     * 事件表录入
     * @return void
     * @throws Exception
     */
    private function _event_dic()
    {
        foreach (DicEventType::EVENT_TYPE as $event_id => $row){
            if ($row){
                $event_desc = $row[1];
                $value = ShopingConn::getConn()
                    ->table(Table::Table_Orders_Event_Dic)
                    ->where('event_id', $event_id)
                    ->value('id');

                // 不存在则输入
                if (!$value){
                    ShopingConn::getConn()
                        ->table(Table::Table_Orders_Event_Dic)
                        ->where('event_id', $event_id)
                        ->insert(['event_id' => $event_id,'event_desc' => $event_desc]);
                }else{
                    ShopingConn::getConn()
                        ->table(Table::Table_Orders_Event_Dic)
                        ->where('event_id', $event_id)
                        ->update(['event_desc' => $event_desc]);
                }
            }
        }
    }


    // 处理 order 表的 event_id 字段
    private function _event_order(){

        // 补全 为0的
        $list = ShopingConn::getConn()
            ->table(Table::Table_Order_Notify_Logs)
            ->where('dh', 0)
            ->where('event_time', '<>', 0)
            ->field('id,event_time')
            ->select();
        if ($list){
            foreach ($list as $row){
                $id = $row['id'];
                $event_time = $row['event_time'];
                $dh = date('ymdH',$event_time);
                ShopingConn::getConn()->table(Table::Table_Order_Notify_Logs)->where('id',$id)->update(['dh' => $dh]);
            }
        }
    }

    /**
     * 订单表的  order_id 字段填充
     * @return void
     * @throws DbException
     * @throws Exception
     * @throws PDOException
     */
    private function _event_order_main(){
        $list = ShopingConn::getConn()
            ->table(Table::Table_Order_Notify_Logs)
            ->where('dh', $this->dh)
            ->where('order_id', '>', 1)
            ->where('event_type','<>',Table::ZWF)
            ->field('id,event_time,event_type,order_id')
            ->select();
        if ($list){

            // 事件词典
            $dics = [];$dic_msgs = [];
            foreach (DicEventType::EVENT_TYPE as $event_id => $erow){
                $dics[$erow[0]] = $event_id;
                $dic_msgs[$erow[0]] = $erow[1];
            }

            $arr_by_order = [];
            foreach ($list as $row){
                $arr_by_order[$row['order_id']][] = $row;
            }

            foreach ($arr_by_order as $order_id => $orows)
            {
                $has_do = false;
                $event_times = array_column($orows,'event_time');
                $need_event_time = max($event_times);
                $event_types = [];
                foreach ($orows as $orow){
                    if ($orow['event_time'] == $need_event_time){
                        $event_types[] = $orow['event_type'];
                    }
                }
                $event_types = array_unique($event_types);
                if (count($event_types) == 1){
                    if (isset($dics[$event_types[0]])){
                        ShopingConn::getConn()
                            ->table(Table::Table_Order)
                            ->where('id',$order_id)
                            ->update(['event_id' => $dics[$event_types[0]]]);
                    }else{
                        ShopingConn::wechatRobot(__METHOD__."需补充dic:".$event_types[0]);
                    }
                }else{
                    sort($event_types);
                    $event_types_str = implode('-',$event_types);
                    $ev = $this->event_orders_asc;
                    foreach ($ev as $kk => $v){
                        $kk = explode('-',$kk);
                        sort($kk);
                        if (implode('-',$kk) == $event_types_str)
                        {
                            if (isset($dics[$v])){
                                ShopingConn::getConn()
                                    ->table(Table::Table_Order)
                                    ->where('id',$order_id)
                                    ->update(['event_id' => $dics[$v]]);
                                $has_do = true;
                            }else{
                                ShopingConn::wechatRobot(__METHOD__."需补充dic:".$v);
                            }
                        }
                    }

                    if (!$has_do){
                        ShopingConn::wechatRobot(__METHOD__."需补充 组合 :".$event_types_str);
//                        foreach ($event_types as &$v) {
//                            $v = $v.'('.$dic_msgs[$v].')';
//                        }

//                        $this->all[$event_types_str] = implode('---',$event_types);
//                        echo implode('---',$event_types)."\r\n";
                    }
                }
            }
        }

        $this->all = array_unique($this->all);
    }

    private $all = [];


    /**
     * 充实 事件值
     * @return void
     * @throws DbException
     * @throws Exception
     */
    private function _event(){
        ShopingConn::getConn()
            ->table(Table::Table_Order_Notify_Logs)
            ->where('event_time',0)
            ->chunk(100,function ($datas) {
                if ($datas) {
                    foreach ($datas as $data) {
                        $params = $data['params'];
                        $params = json_decode($params,true);
                        if (!$params){
                            $this->_event_default($data['id']);
                        }else{
                            //P卡
                            $statusCode = empty($params['statusCode']) ? '' : $params['statusCode'];
                            $created_at = empty($params['created_at']) ? 0 : strtotime($params['created_at']);
                            if ($created_at && $statusCode && empty($params['createdAt'])){
                                if (isset($params['reasonCode'])){
                                    $statusCode .= '.'.$params['reasonCode'];
                                }elseif (isset($params['statusReason'])){
                                    $statusCode .= '.'.$params['statusReason'];
                                }
                                $this->_event_appoint($data['id'],$created_at,$statusCode);
                            }else{

                                // PayPal
                                $event_type = empty($params['event_type']) ? Table::ZWF : $params['event_type'];
                                $create_time = empty($params['create_time']) ? 0 : strtotime($params['create_time']);
                                if ($create_time){
                                    $this->_event_appoint($data['id'],$create_time,$event_type);
                                }else{
                                    // 云汇
                                    // PayPal
                                    $event_type = empty($params['name']) ? Table::ZWF : $params['name'];
                                    $create_time = empty($params['createdAt']) ? 0 : strtotime($params['createdAt']);
                                    if ($create_time){
                                        $this->_event_appoint($data['id'],$create_time,$event_type);
                                    }else{

                                        $this->_event_default($data['id']);
//                                        var_export($params);
//                                        exit();
                                    }
                                }
                            }
                        }
                    }
                }
            });
    }

    /**
     * 默认事件
     * @param $id
     * @return void
     * @throws DbException
     * @throws Exception
     * @throws PDOException
     */
    private function _event_default($id){
        ShopingConn::getConn()
            ->table(Table::Table_Order_Notify_Logs)
            ->where('id',$id)
            ->update(["event_time" => 1,"event_type" => Table::ZWF]);
    }

    private function _event_appoint($id,$create_time,$event_type){
        $dh = date('ymdH',$create_time);
        ShopingConn::getConn()
            ->table(Table::Table_Order_Notify_Logs)
            ->where('id',$id)
            ->update(["event_time" => $create_time,"event_type" => $event_type,'dh' => $dh]);
    }
}
